using System;
using System.Collections.Generic;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;

namespace UniAspect.Aspect.Emit
{
    /// <summary>
    /// Use it on the root container only!
    /// </summary>
    [Obsolete]
    public class AspectInsertionExtensionEmit : UnityContainerExtension, IAspectInsertionExtension
    {
        protected override void Initialize()
        {
            //
            // Main strategy chain
            //
            Context.Strategies.Clear();
            Context.Strategies.AddNew<BuildKeyMappingStrategy>(UnityBuildStage.TypeMapping);
            Context.Strategies.AddNew<LifetimeStrategy>(UnityBuildStage.Lifetime);

            Context.Strategies.AddNew<BuildPlanStrategy>(UnityBuildStage.Creation);

            //
            // Build plan strategy chain
            //
            Context.BuildPlanStrategies.Clear();
            Context.BuildPlanStrategies.AddNew<AspectInsertionStrategy>(UnityBuildStage.Creation);
            Context.BuildPlanStrategies.AddNew<DynamicMethodPropertySetterStrategy>(UnityBuildStage.Initialization);
            Context.BuildPlanStrategies.AddNew<DynamicMethodCallStrategy>(UnityBuildStage.Initialization);

            Context.Policies.SetDefault<IAspectInsertionPolicy>(new AspectInsertionPolicy());
        }

        public IList<IAspect> Aspects<T>()
        {
            return Aspects<T>(null);
        }

        public IList<IAspect> Aspects<T>(string name)
        {
            return Aspects(typeof(T), name);
        }

        public IList<IAspect> Aspects(Type type)
        {
            return Aspects(type, null);
        }

        public IList<IAspect> Aspects(Type type, string name)
        {
            return Context.Policies
                    .Get<IAspectInsertionPolicy>(new NamedTypeBuildKey(type, name))
                    .Aspects;
        }
    }
}